package com.nutrition.health.service;

import com.nutrition.health.model.DietRecord;
import com.nutrition.health.model.DietRecord.MealType;
import java.util.Map;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public interface DietRecordService {
    
    List<DietRecord> getAllDietRecordsByUserId(Long userId);
    
    Page<DietRecord> getAllDietRecordsByUserId(Long userId, Pageable pageable);
    
    Optional<DietRecord> getDietRecordById(Long id);
    
    List<DietRecord> getDietRecordsByUserIdAndMealType(Long userId, MealType mealType);
    
    List<DietRecord> getDietRecordsByUserIdAndDateRange(Long userId, LocalDate startDate, LocalDate endDate);
    
    DietRecord createDietRecord(Long userId, DietRecord dietRecord);
    
    DietRecord updateDietRecord(Long id, DietRecord dietRecordDetails);
    
    void deleteDietRecord(Long id);
    
    /**
     * 添加食品到饮食记录
     * @param dietRecordId 饮食记录ID
     * @param foodItemId 食品ID
     * @return 更新后的饮食记录
     */
    DietRecord addFoodItemToDietRecord(Long dietRecordId, Long foodItemId);
    
    /**
     * 从饮食记录中移除食品
     * @param dietRecordId 饮食记录ID
     * @param foodItemId 食品ID
     * @return 更新后的饮食记录
     */
    DietRecord removeFoodItemFromDietRecord(Long dietRecordId, Long foodItemId);
    
    /**
     * 计算用户在指定日期范围内的总卡路里摄入
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 总卡路里摄入
     */
    double calculateTotalCaloriesForUserInDateRange(Long userId, LocalDate startDate, LocalDate endDate);
    
    /**
     * 计算用户在指定日期范围内的营养素摄入
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 营养素摄入映射（键为营养素名称，值为摄入量）
     */
    Map<String, Double> calculateNutrientIntakeForUserInDateRange(Long userId, LocalDate startDate, LocalDate endDate);
    
    /**
     * 分析用户的饮食模式
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 饮食模式分析结果
     */
    Map<String, Object> analyzeDietaryPatterns(Long userId, LocalDate startDate, LocalDate endDate);
    
   /**
    * 比较用户的实际营养摄入与推荐摄入
    * @param userId 用户ID
    * @param date 日期
    * @return 比较结果
    */
   Map<String, Object> compareActualVsRecommendedIntake(Long userId, LocalDate date);
   
   /**
    * 获取用户在指定日期范围内的营养趋势数据
    * @param userId 用户ID
    * @param startDate 开始日期
    * @param endDate 结束日期
    * @return 营养趋势数据
    */
   Map<String, Object> getNutritionTrend(Long userId, LocalDate startDate, LocalDate endDate);
   
   /**
    * 获取用户在指定日期的营养素占比数据
    * @param userId 用户ID
    * @param date 日期
    * @param period 周期（daily或weekly）
    * @return 营养素占比数据
    */
   Map<String, Object> getNutritionRatio(Long userId, LocalDate date, String period);
   
   /**
    * 获取用户在指定日期的热量摄入目标完成情况
    * @param userId 用户ID
    * @param date 日期
    * @return 热量摄入目标完成情况数据
    */
   Map<String, Object> getCalorieGoalCompletion(Long userId, LocalDate date);
   
   /**
    * 获取用户在指定周期内的营养素摄入与推荐值对比数据
    * @param userId 用户ID
    * @param date 日期
    * @param period 周期（weekly或monthly）
    * @return 营养素摄入与推荐值对比数据
    */
   Map<String, Object> getNutritionComparison(Long userId, LocalDate date, String period);
   
   /**
    * 获取用户在指定周期内的食物类型摄入分布数据
    * @param userId 用户ID
    * @param date 日期
    * @param period 周期（weekly或monthly）
    * @return 食物类型摄入分布数据
    */
   Map<String, Object> getFoodCategoryDistribution(Long userId, LocalDate date, String period);
   
   /**
    * 创建饮食记录并同时添加多个食品（一次性计算营养信息）
    * @param userId 用户ID
    * @param dietRecord 饮食记录对象
    * @param foodItems 食品列表，每个食品包含名称和克数
    * @return 创建的饮食记录
    */
   DietRecord createDietRecordWithFoodItems(Long userId, DietRecord dietRecord, List<Map<String, Object>> foodItems);
   
   /**
    * 获取用户在指定日期范围内的BMI趋势数据
    * @param userId 用户ID
    * @param startDate 开始日期
    * @param endDate 结束日期
    * @return BMI趋势数据
    */
   Map<String, Object> getBMITrend(Long userId, LocalDate startDate, LocalDate endDate);
}